from typing import List
from fastapi import APIRouter, Depends, Request
from fastapi_async_sqlalchemy import db
from fastapi_pagination import Params
from fastapi_pagination.ext.async_sqlalchemy import paginate
from sqlmodel import select

from conf.config import BusinessType
from core.database import DBSession
from core.exception.errors import ErrorException
from core.log_decorator import sys_log
from core.response import create_response
from core.security import verify_password, get_password_hash
from crud.admin_cruds.group_crud import curd_admin_group
from crud.admin_cruds.login_log_crud import crud_login_log
from crud.admin_cruds.oper_log_crud import crud_oper_log
from crud.admin_cruds.user_crud import curd_admin_user
from depends.admin_depends.auth import permission_meta_infos, get_current_user, check_permission
from models import operLog, loginLog
from models.admin.user_model import AdminUser, ManageGroup, ManageGroupBase
from schemas.admin_schemas.admin_schema import AdminUserUpdate, AdminUserCreate, AdminUserItem, ChangePassword, \
    SysLogQuery
from schemas.common_schema import ResponsePage, ResponseBase
from services.admin_services.admin_service import AdminService
from services.admin_services.cache_service import CacheService

admin_user_router = APIRouter()


@admin_user_router.get("/get_sys_permissions", summary="获取系统权限列表")
async def get_sys_permissions():
    def build_tree(data):
        result = []
        for key, value in data.items():
            node = {'label': key, 'children': [], 'nodeKey': key}
            if isinstance(value, list):
                for item in value:
                    node['children'].append({'label': item, 'nodeKey': f"{key}.{item}"})
            elif isinstance(value, dict):
                node['children'] = build_tree(value)
            result.append(node)
        return result
    ret_data = build_tree(permission_meta_infos)
    return create_response(data=ret_data)


@admin_user_router.get("/get_permissions", summary="获取管理员自身权限")
async def get_permissions(db: DBSession, current_user=Depends(get_current_user)):
    group = await curd_admin_group.get(pk=current_user.group_id)
    if not group:
        raise ErrorException("用户分组不存在")
    return create_response(data=group.roles)


@admin_user_router.post("/add_admin_user", summary="添加管理员", dependencies=[Depends(check_permission(model_name="管理员", func_name="新增"))])
@sys_log(title='管理员', business_type=BusinessType.INSERT)
async def add_admin_user(db: DBSession, admin_user_create: AdminUserCreate):
    """
    添加管理员
    :param db: db_session
    :param admin_user_create: 超级管理员
    :return:
    """
    admin_service = AdminService(db)
    await admin_service.create_admin_user(admin_user_create)
    return create_response()


@admin_user_router.post("/edit_admin_user", summary="编辑管理员", dependencies=[Depends(check_permission(model_name="管理员", func_name="编辑"))])
@sys_log(title='管理员', business_type=BusinessType.EDIT)
async def edit_admin_user(admin_user_update: AdminUserUpdate):
    """
    编辑管理员
    :param db: db_session
    :param admin_user_update: 超级管理员
    :return:
    """
    admin_service = AdminService()
    await admin_service.edit_admin_user(admin_user_update)
    return create_response()


@admin_user_router.get("/get_admin_user", summary="获取管理员列表", response_model=ResponsePage[List[AdminUserItem]], dependencies=[Depends(check_permission(model_name="管理员", func_name="列表"))])
@sys_log(title='管理员', business_type=BusinessType.GET)
async def get_admin_user(params: Params = Depends()):
    query = select(AdminUser, ManageGroup).join(ManageGroup, AdminUser.group_id == ManageGroup.id)
    result = await paginate(db.session, query, params)
    user_items = [AdminUserItem.from_orm(item[0], update={"group_name": item[1].group_name if item[1] else ''}) for item in result.items]
    result.items = user_items
    return create_response(data=result)


@admin_user_router.get("/get_admin_user/{user_id}", summary="获取管理员详情", dependencies=[Depends(check_permission(model_name="管理员", func_name="详情"))])
async def get_admin_user_by_id(user_id: int):
    user = await curd_admin_user.get_row(key="id", value=user_id)
    if not user:
        raise ErrorException("用户不存在")
    return create_response(user)


@admin_user_router.post("/delete_admin_user/{user_id}", summary="删除管理员", dependencies=[Depends(check_permission(model_name="管理员", func_name="删除"))])
@sys_log(title='管理员', business_type=BusinessType.DELETE)
async def delete_admin_user(user_id: int, current_user: AdminUser = Depends(get_current_user)):
    if current_user.id == user_id:
        raise ErrorException("不能删除自身")
    user = await curd_admin_user.get_row(key="id", value=user_id)
    if not user:
        raise ErrorException("用户不存在")
    await curd_admin_user.delete(db=db, pk=user_id)
    return create_response()


@admin_user_router.post("/change_password", summary="修改密码")
@sys_log(title='管理员', business_type=BusinessType.EDIT)
async def change_password(change_pass: ChangePassword, current_user: AdminUser = Depends(get_current_user)):
    """
    修改密码
    :param current_user: 当前用户
    :param change_pass: 密码参数
    :return:
    """

    user = await curd_admin_user.get(pk=current_user.id)
    if not verify_password(change_pass.old_password, user.hashed_password):
        raise ErrorException("原密码不正确")
    if not user:
        raise ErrorException("用户不存在")
    user.hashed_password = get_password_hash(change_pass.password)
    await db.session.merge(user)
    return create_response()


@admin_user_router.get("/get_manage_group", summary="获取分组列表", dependencies=[Depends(check_permission(model_name="权限分组", func_name="列表"))])
async def get_manage_group(params: Params = Depends()):
    query = select(ManageGroup)
    group_list = await paginate(db.session, query, params)
    return create_response(data=group_list)


@admin_user_router.post("/add_manage_group", summary="新增权限分组", dependencies=[Depends(check_permission(model_name="权限分组", func_name="新增"))])
@sys_log(title='分组', business_type=BusinessType.INSERT)
async def add_manage_group(group: ManageGroupBase):
    query = select(ManageGroup).where(ManageGroup.group_name == group.group_name)
    group_ret = await db.session.execute(query)
    db_group = group_ret.scalar_one_or_none()
    if db_group:
        raise ErrorException("当前分组已存在")
    db_obj = ManageGroup.from_orm(group)
    db.session.add(db_obj)
    return create_response()


@admin_user_router.post("/edit_manage_group", summary="编辑权限分组", dependencies=[Depends(check_permission(model_name="权限分组", func_name="编辑"))])
@sys_log(title='编辑权限分组', business_type=BusinessType.EDIT)
async def edit_manage_group(group: ManageGroup):
    other_query = select(ManageGroup).where(ManageGroup.id != group.id, ManageGroup.group_name == group.group_name)
    other_group_ret = await db.session.execute(other_query)
    if other_group_ret.scalar_one_or_none():
        raise ErrorException("分组名不能与其它分组名相同")
    current_group = await curd_admin_group.get(pk=group.id)
    if not current_group:
        raise ErrorException("分组不存在")
    await curd_admin_group.update(obj_new=group, obj_current=current_group)
    return create_response()


@admin_user_router.get("/get_manage_group/{group_id}", summary="获取权限分组详情", response_model=ResponseBase[ManageGroup])
async def get_edit_manage_group(group_id: int):
    manage_group = await curd_admin_group.get(pk=group_id)
    if not manage_group:
        raise ErrorException("分组不存在")
    return create_response(manage_group)


@admin_user_router.post("/delete_manage_group/{group_id}", summary="删除权限分组", dependencies=[Depends(check_permission(model_name="权限分组", func_name="删除"))])
@sys_log(title='分组', business_type=BusinessType.DELETE)
async def delete_manage_group(group_id: int, current_user: AdminUser = Depends(get_current_user)):
    query = select(AdminUser).where(AdminUser.group_id == group_id)
    user_ret = await db.session.execute(query)
    if user_ret.scalar_one_or_none():
        raise ErrorException("删除前请把当前组下的用户转到其它分组")
    if current_user.group_id == group_id:
        raise ErrorException("不能删除自身权限组")
    group = await curd_admin_group.get(pk=group_id)
    if not group:
        raise ErrorException("分组不存在")
    await curd_admin_group.delete(pk=group_id)
    return create_response()


@admin_user_router.get("/get_sys_logs", summary="操作日志", dependencies=[Depends(check_permission(model_name="操作日志", func_name="列表"))])
async def get_sys_logs(query_params: SysLogQuery = Depends(), params: Params = Depends()):
    query = select(operLog).order_by(operLog.create_time.desc())
    if query_params.ip:
        query = query.filter(operLog.ip == query_params.ip)
    if query_params.username:
        query = query.filter(operLog.username == query_params.username)
    if query_params.method:
        query = query.filter(operLog.method == query_params.method)

    logs = await crud_oper_log.get_multi_paginated(params=params, query=query)
    return create_response(logs)


@admin_user_router.get("/get_login_logs", summary="登录日志", dependencies=[Depends(check_permission(model_name="登录日志", func_name="列表"))])
async def get_login_logs(query_params: SysLogQuery = Depends(), params: Params = Depends()):
    query = select(loginLog).order_by(loginLog.create_time.desc())
    if query_params.ip:
        query = query.filter(loginLog.ip_address == query_params.ip)
    if query_params.username:
        query = query.filter(loginLog.username == query_params.username)

    logs = await crud_login_log.get_multi_paginated(params=params, query=query)
    return create_response(logs)


@admin_user_router.get("/get_cache_names", summary="获取缓存配置名称",
                       dependencies=[Depends(check_permission(model_name="缓存", func_name="缓存配置名"))])
async def get_cache_names():

    cache_name_list_result = await CacheService.get_cache_monitor_cache_name_services()
    return create_response(cache_name_list_result)


@admin_user_router.get('/clear_cache/{cache_name}', summary="清除缓存",
                       dependencies=[Depends(check_permission(model_name="缓存", func_name="清除缓存"))])
async def clear_monitor_cache_name(cache_name: str):
    await CacheService.clear_cache_monitor_cache_name_services(cache_name)
    return create_response()


@admin_user_router.get('/get_cache_keys/{cache_name}', summary="获取key列表",
                       dependencies=[Depends(check_permission(model_name="缓存", func_name="获取key列表"))])
async def get_cache_keys(cache_name: str):
    cache_keys = await CacheService.get_cache_monitor_cache_key_services(cache_name)
    return create_response(cache_keys)


@admin_user_router.get('/get_cache_value/{cache_name}/{cache_key}', summary="获取缓存值",
                       dependencies=[Depends(check_permission(model_name="缓存", func_name="获取缓存值"))])
async def get_cache_value(cache_name: str, cache_key: str):
    data = await CacheService.get_cache_monitor_cache_value_services(cache_name, cache_key)
    return create_response(data)


@admin_user_router.get('/clear_cache_key/{cache_key}', summary="删除指定key",
                       dependencies=[Depends(check_permission(model_name="缓存", func_name="删除指定key"))])
async def clear_monitor_cache_key(cache_key: str):
    await CacheService.clear_cache_monitor_cache_key_services(cache_key)
    return create_response()
